package com.usian.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usian.common.exception.CatchCustomException;
import com.usian.common.exception.code.UserStatusCode;
import com.usian.model.article.pojos.ApAuthor;
import com.usian.model.behavior.dtos.FollowBehaviorDto;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.user.dtos.UserRelationDto;
import com.usian.model.user.pojos.ApUser;
import com.usian.model.user.pojos.ApUserFan;
import com.usian.model.user.pojos.ApUserFollow;
import com.usian.user.feign.ArticleFeign;
import com.usian.user.mapper.ApUserFanMapper;
import com.usian.user.mapper.ApUserFollowMapper;
import com.usian.user.mapper.ApUserMapper;
import com.usian.user.service.ApUserRelationService;
import com.usian.user.threadlocal.AppThreadLocalUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@SuppressWarnings("ALL")
public class UserRelationServiceImpl implements ApUserRelationService {
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private ApUserMapper apUserMapper;

    @Autowired
    private ApUserFollowMapper apUserFollowMapper;

    @Autowired
    private ApUserFanMapper apUserFanMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public ResponseResult follow(UserRelationDto dto) {
        //1.参数检查
        // 关注与取消关注0  关注 1  取消
        if(dto.getOperation() == null || dto.getOperation()<0 || dto.getOperation() > 1){
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"关注有误，请重新进行关注");
        }
        //关注  作者id
        if(dto.getAuthorId() == null){
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"作者信息不能为空");
        }
//根据id获取user对象
        Integer id = AppThreadLocalUtils.getUser().getId();
        ApUser apUser1 = apUserMapper.selectById(id);
        AppThreadLocalUtils.setUser(apUser1);



        //2.根据作者id先查询作者信息  判断作者信息是否为空  如果为空  则证明有问题
        Integer followId = null;//被关注的用户id（就是有作者权限的用户  即被关注的作者id）
        ApAuthor apAuthor = articleFeign.findById(dto.getAuthorId());
        if(apAuthor != null){
            //获取需要关注的作者的id
            followId = apAuthor.getUserId();
        }
        if(followId == null){
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"关注的作者不存在");
        }else{
            //获取当前登录用户（需要关注或者取消关注的当前登录的id账号
            ApUser apUser = AppThreadLocalUtils.getUser();
            if(apUser!= null){
                //用户执行关注操作
                if(dto.getOperation() == 0){
                    //3.如果当前操作是0 创建数据（app用户关注信息和app的用户粉丝信息）
                     followByUserId(apUser,followId,dto.getArticleId());
                }else{
                    //取消关注
                    //4.如果当前操作是1 删除数据（app用户关注信息和app的用户粉丝信息）
                    followCancelByUserId(apUser,followId);
                }
            }else{
                CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"该用户没有登录，无法进行关注");
            }
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }

    /**
     * 关注
     * @param apUser  执行关注操作的用户
     * @param followId  被关注的作者id
     * @param articleId  文章id
     * @return
     */
    @Transactional       //默认走运行时异常
    private void followByUserId(ApUser apUser, Integer followId, Long articleId) {
        //判断用户是否已经关注过了  如果关注  提示  如果没有关注  才开始保存  保存需要保存两张表  粉丝表  关注表
        //判断当前关注人是否存在
        ApUserFollow apUserFollow = apUserFollowMapper.selectOne(Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getUserId, apUser.getId())
                .eq(ApUserFollow::getFollowId, followId));
        if(apUserFollow == null){
            //保存         保存app用户关注信息
            apUserFollow=new ApUserFollow();
            apUserFollow.setFollowName(apUser.getName());
            apUserFollow.setLevel((short)0);
            apUserFollow.setIsNotice(true);
            apUserFollow.setCreatedTime(new Date());
            apUserFollow.setUserId(apUser.getId());
            apUserFollow.setFollowId(followId);
            apUserFollowMapper.insert(apUserFollow);
        //保存数据  ap_user_follow  ap_user_fan
            ApUserFan apUserFan = apUserFanMapper.selectOne(Wrappers.<ApUserFan>lambdaQuery()
                    .eq(ApUserFan::getUserId, followId)
                    .eq(ApUserFan::getFansId, apUser.getId()));
            if (apUserFan==null){
                //保存app用户粉丝信息
                apUserFan = new ApUserFan();
                apUserFan.setUserId(followId);
                apUserFan.setFansId(apUser.getId().longValue());
                apUserFan.setFansName(apUser.getName());
                apUserFan.setLevel((short)0);
                apUserFan.setIsDisplay(true);
                apUserFan.setIsShieldLetter(false);
                apUserFan.setIsShieldComment(false);
                apUserFan.setCreatedTime(new Date());
                apUserFanMapper.insert(apUserFan);
            }
    //设置rabbitmq消息队列
            FollowBehaviorDto dto = new FollowBehaviorDto();
            dto.setUserId(apUser.getId());
            dto.setArticleId(articleId);
            dto.setFollowId(followId);
            rabbitTemplate.convertAndSend("BehaviorExchange","Behavior", JSON.toJSONString(dto));
        }else {
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"该作者已经关注");
        }


    }

    /**
     * 取消关注
     * @param apUser   当前登录用户id
     * @param followId  被关注用户id（即作者账号的userid）
     * @return
     */
    private void followCancelByUserId(ApUser apUser, Integer followId) {
        //先查再删
        ApUserFollow apUserFollow = apUserFollowMapper.selectOne(Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getUserId, apUser.getId())
                .eq(ApUserFollow::getFollowId, followId));
        if(apUserFollow == null){
            CatchCustomException.catchs(UserStatusCode.PARAM_FAIL,"作者没有被关注");
        }else{
            //删除用户粉丝信息  查询粉丝信息
            ApUserFan apUserFan = apUserFanMapper.selectOne(Wrappers.<ApUserFan>lambdaQuery()
                    .eq(ApUserFan::getUserId, followId)
                    .eq(ApUserFan::getFansId, apUser.getId()));
            //删除用户粉丝信息
            if(apUser != null){
                apUserFanMapper.delete(Wrappers.<ApUserFan>lambdaQuery().eq(ApUserFan::getUserId, followId).eq(ApUserFan::getFansId, apUser.getId()));
            }
            //删除用户关注信息
            apUserFollowMapper.delete(Wrappers.<ApUserFollow>lambdaQuery()
                    .eq(ApUserFollow::getUserId, apUser.getId())
                    .eq(ApUserFollow::getFollowId, followId));

        }
    }
}
